/*
* Project: VD Kit
* Module: module_name
* File: wav_pcm.c
* Created Date: 2023-11-28 22:28:26
* Author: Huangjc
* Description: description
*
*历史记录：
* -----
* Modified: 2023-11-28 22:28:26
* Modified By: Huangjc
* Comments: v1.0 初版
* -----
*
* Copyright (c) 2023 - vDiscovery, Inc
*/


/* ======================================================================================
* includes
* 添加头文件位置
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* ======================================================================================
* macros
* 宏定义位置
*/


/* ======================================================================================
* log
* log标志位置
*/
#ifdef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "TAG"
#endif


/* ======================================================================================
* extern
* 外部定义变量或函数位置
*/


/* ======================================================================================
* declaration
* 函数声明位置
*/


/* ======================================================================================
* types
* 类型定义位置
*/

// WAV文件头信息结构体
typedef struct {
    char chunkID[4];
    int chunkSize;
    char format[4];
    char subchunk1ID[4];
    int subchunk1Size;
    short audioFormat;
    short numChannels;
    int sampleRate;
    int byteRate;
    short blockAlign;
    short bitsPerSample;
    char subchunk2ID[4];
    int subchunk2Size;
} WAVHeader;
      
/* ======================================================================================
* globals
* 全局变量位置
*/


/* ======================================================================================
* private implementation
* 本模块私有函数位置
*/


/* ======================================================================================
* implementation
* 本模块对外函数位置
*/
int main(int argc,char **argv)
{
    unsigned char data[46];

    if(argc != 2)
    {
        printf("input file \n");
        return -1;
    }

    printf("%s \n",argv[argc-1]);

    FILE* file = fopen(argv[argc-1], "rb");
    if (file == NULL) {
        printf("Failed to open WAV file.\n");
        return 1;
    }

    WAVHeader header;
    fread(data, 46, 1, file);

    memcpy((unsigned char *)&header.chunkID,data,4);
    memcpy((unsigned char *)&header.chunkSize,data+4,4);
    memcpy((unsigned char *)&header.format,data+8,4);
    memcpy((unsigned char *)&header.subchunk1ID,data+12,4);
    memcpy((unsigned char *)&header.subchunk1Size,data+16,4);
    memcpy((unsigned char *)&header.audioFormat,data+20,2);
    memcpy((unsigned char *)&header.numChannels,data+22,2);
    memcpy((unsigned char *)&header.sampleRate,data+24,4);
    memcpy((unsigned char *)&header.byteRate,data+28,4);
    memcpy((unsigned char *)&header.blockAlign,data+32,2);
    memcpy((unsigned char *)&header.bitsPerSample,data+34,2);
    memcpy((unsigned char *)&header.subchunk2ID,data+38,4);
    memcpy((unsigned char *)&header.subchunk2Size,data+42,4);

    printf("WAVHeader size %ld \n",sizeof(WAVHeader));
    printf("Head string \"%c%c%c%c\" \n",header.chunkID[0],header.chunkID[1],header.chunkID[2],header.chunkID[3]);
    printf("All size %d \n",header.chunkSize);
    printf("format string \"%c%c%c%c\" \n",header.format[0],header.format[1],header.format[2],header.format[3]);
    printf("subchunk1ID string \"%c%c%c%c\" \n",header.subchunk1ID[0],header.subchunk1ID[1],header.subchunk1ID[2],header.subchunk1ID[3]);
    printf("subchunk1Size size: %d\n", header.subchunk1Size);
    printf("audioFormat %d\n",header.audioFormat);
    printf("Channels: %d\n", header.numChannels);
    printf("Sample Rate: %d\n", header.sampleRate);
    printf("byteRate: %d\n", header.byteRate);
    printf("blockAlign: %d\n", header.blockAlign);
    printf("Bits per Sample: %d\n", header.bitsPerSample);
    printf("subchunk2ID string \"%c%c%c%c\" \n",header.subchunk2ID[0],header.subchunk2ID[1],header.subchunk2ID[2],header.subchunk2ID[3]);
    printf("subchunk2Size: %d\n", header.subchunk2Size);

    #if 0
    short* pcmData = (short*)malloc(header.subchunk2Size);
    fread(pcmData, sizeof(short), header.subchunk2Size / sizeof(short), file);

    // 创建PCM文件
    FILE* pcmFile = fopen("output.pcm", "wb");
    if (pcmFile == NULL) {
        printf("Failed to create PCM file.\n");
        return 1;
    }

    // 写入数据
    fwrite(pcmData, sizeof(short), header.subchunk2Size / sizeof(short), pcmFile);

    fclose(pcmFile);
    free(pcmData);

    #endif

    FILE* pcmFile = fopen("output.pcm", "wb");
    if (pcmFile == NULL) {
        printf("Failed to create PCM file.\n");
        return 1;
    }

    unsigned char pcm[4096];
    int rtotal = 0;
    int rlen = 0;
    int wtotal = 0;
    int wlen = 0;
    int diff = 0;
 
    while(rtotal != header.subchunk2Size)
    {
        memset(pcm,0,4096);
        diff = header.subchunk2Size - rtotal;
        if( diff >= 4096 )
        {
            rlen = fread(pcm, 1, 4096, file);
        }
        else
        {
            rlen = fread(pcm, 1, diff, file);
        }
        rtotal += rlen;

        printf("rtotal %d rlen %d ",rtotal,rlen);

        wlen = fwrite(pcm, 1, rlen, pcmFile);

        if( rlen != wlen )
        {
            printf("read and write sizeof wrong R=%d W=%d",rlen,wlen);
            fseek(pcmFile, wtotal, SEEK_SET);
            rtotal -= rlen;
            fseek(file, rtotal, SEEK_SET);
            continue;
        }

        wtotal += wlen;

        printf("wtotal %d wlen %d \r\n",wtotal,wlen);
    }

    fclose(pcmFile);
    
    fclose(file);

    return 0;

}